// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/base/media_switches.h"

#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/chromecast_buildflags.h"
#include "build/chromeos_buildflags.h"
#include "components/system_media_controls/linux/buildflags/buildflags.h"
#include "gpu/config/gpu_finch_features.h"
#include "media/media_buildflags.h"

#if BUILDFLAG(IS_LINUX)
#include "base/cpu.h"
#endif

namespace switches {

// Allow users to specify a custom buffer size for debugging purpose.
const char kAudioBufferSize[] = "audio-buffer-size";

#if BUILDFLAG(ENABLE_PASSTHROUGH_AUDIO_CODECS)
// Audio codecs supported by the HDMI sink is retrieved from the audio
// service process. EDID contains the Short Audio Descriptors, which list
// the audio decoders supported, and the information is presented as a
// bitmask of supported audio codecs.
const char kAudioCodecsFromEDID[] = "audio-codecs-from-edid";
#endif  // BUILDFLAG(ENABLE_PASSTHROUGH_AUDIO_CODECS)

// Set a timeout (in milliseconds) for the audio service to quit if there are no
// client connections to it. If the value is negative the service never quits.
const char kAudioServiceQuitTimeoutMs[] = "audio-service-quit-timeout-ms";

// Command line flag name to set the autoplay policy.
const char kAutoplayPolicy[] = "autoplay-policy";

const char kDisableAudioOutput[] = "disable-audio-output";
#if defined(OHOS_WEBRTC)
const char kDisableAudioInput[] = "disable-audio-input";
#endif // defined(OHOS_WEBRTC)

// Causes the AudioManager to fail creating audio streams. Used when testing
// various failure cases.
const char kFailAudioStreamCreation[] = "fail-audio-stream-creation";

// Set number of threads to use for video decoding.
const char kVideoThreads[] = "video-threads";

// Do not immediately suspend media in background tabs.
const char kDisableBackgroundMediaSuspend[] =
    "disable-background-media-suspend";

// Force to report VP9 as an unsupported MIME type.
const char kReportVp9AsAnUnsupportedMimeType[] =
    "report-vp9-as-an-unsupported-mime-type";

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FREEBSD) || \
    BUILDFLAG(IS_SOLARIS)
// The Alsa device to use when opening an audio input stream.
const char kAlsaInputDevice[] = "alsa-input-device";
// The Alsa device to use when opening an audio stream.
const char kAlsaOutputDevice[] = "alsa-output-device";
#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ||
        // BUILDFLAG(IS_FREEBSD) || BUILDFLAG(IS_SOLARIS)

#if BUILDFLAG(IS_WIN)
// Use exclusive mode audio streaming for Windows Vista and higher.
// Leads to lower latencies for audio streams which uses the
// AudioParameters::AUDIO_PCM_LOW_LATENCY audio path.
// See http://msdn.microsoft.com/en-us/library/windows/desktop/dd370844.aspx
// for details.
const char kEnableExclusiveAudio[] = "enable-exclusive-audio";

// Use Windows WaveOut/In audio API even if Core Audio is supported.
const char kForceWaveAudio[] = "force-wave-audio";

// Instead of always using the hardware channel layout, check if a driver
// supports the source channel layout.  Avoids outputting empty channels and
// permits drivers to enable stereo to multichannel expansion.  Kept behind a
// flag since some drivers lie about supported layouts and hang when used.  See
// http://crbug.com/259165 for more details.
const char kTrySupportedChannelLayouts[] = "try-supported-channel-layouts";

// Number of buffers to use for WaveOut.
const char kWaveOutBuffers[] = "waveout-buffers";
#endif  // BUILDFLAG(IS_WIN)

#if BUILDFLAG(IS_FUCHSIA)
// Enables protected buffers for encrypted video streams.
const char kEnableProtectedVideoBuffers[] = "enable-protected-video-buffers";

// Forces protected memory for all output video buffers generated by
// FuchsiaVideoDecoder, including unencrypted streams. Ignored unless
// --enable-protected-video-buffers is also specified.
const char kForceProtectedVideoOutputBuffers[] =
    "force-protected-video-output-buffers";

const char kDisableAudioInput[] = "disable-audio-input";

// Minimum size for buffer size used for output video frames in
// FuchsiaVideoDecoder. May be set to avoid re-allocating video buffers when an
// application upgrades video resolution mid-stream.
const char kMinVideoDecoderOutputBufferSize[] =
    "min-video-decoder-output-buffer-size";

// Forces AudioManagerFuchsia to assume that the AudioCapturer implements echo
// cancellation.
// TODO(crbug.com/852834): Remove this once AudioManagerFuchsia is updated to
// get this information from AudioCapturerFactory.
const char kAudioCapturerWithEchoCancellation[] =
    "audio-capturer-with-echo-cancellation";
#endif  // BUILDFLAG(IS_FUCHSIA)

#if defined(USE_CRAS)
// Use CRAS, the ChromeOS audio server.
const char kUseCras[] = "use-cras";
// Enforce system audio echo cancellation.
const char kSystemAecEnabled[] = "system-aec-enabled";
#endif  // defined(USE_CRAS)

// For automated testing of protected content, this switch allows specific
// domains (e.g. example.com) to always allow the permission to share the
// protected media identifier. In this context, domain does not include the
// port number. User's content settings will not be affected by enabling this
// switch.
// Reference: http://crbug.com/718608
// Example:
// --unsafely-allow-protected-media-identifier-for-domain=a.com,b.ca
const char kUnsafelyAllowProtectedMediaIdentifierForDomain[] =
    "unsafely-allow-protected-media-identifier-for-domain";

// Use fake device for Media Stream to replace actual camera and microphone.
// For the list of allowed parameters, see
// FakeVideoCaptureDeviceFactory::ParseFakeDevicesConfigFromOptionsString().
const char kUseFakeDeviceForMediaStream[] = "use-fake-device-for-media-stream";

// Use an .y4m file to play as the webcam. See the comments in
// media/capture/video/file_video_capture_device.h for more details.
const char kUseFileForFakeVideoCapture[] = "use-file-for-fake-video-capture";

// Play a .wav file as the microphone. Note that for WebRTC calls we'll treat
// the bits as if they came from the microphone, which means you should disable
// audio processing (lest your audio file will play back distorted). The input
// file is converted to suit Chrome's audio buses if necessary, so most sane
// .wav files should work. You can pass either <path> to play the file looping
// or <path>%noloop to stop after playing the file to completion.
const char kUseFileForFakeAudioCapture[] = "use-file-for-fake-audio-capture";

// Use a fake device for accelerated decoding of MJPEG. This allows, for
// example, testing of the communication to the GPU service without requiring
// actual accelerator hardware to be present.
const char kUseFakeMjpegDecodeAccelerator[] =
    "use-fake-mjpeg-decode-accelerator";

// Disable hardware acceleration of mjpeg decode for captured frame, where
// available.
const char kDisableAcceleratedMjpegDecode[] =
    "disable-accelerated-mjpeg-decode";

// When running tests on a system without the required hardware or libraries,
// this flag will cause the tests to fail. Otherwise, they silently succeed.
const char kRequireAudioHardwareForTesting[] =
    "require-audio-hardware-for-testing";

// Mutes audio sent to the audio device so it is not audible during
// automated testing.
const char kMuteAudio[] = "mute-audio";

// Allows clients to override the threshold for when the media renderer will
// declare the underflow state for the video stream when audio is present.
// TODO(dalecurtis): Remove once experiments for http://crbug.com/470940 finish.
const char kVideoUnderflowThresholdMs[] = "video-underflow-threshold-ms";

// Disables the new rendering algorithm for webrtc, which is designed to improve
// the rendering smoothness.
const char kDisableRTCSmoothnessAlgorithm[] =
    "disable-rtc-smoothness-algorithm";

// Force media player using SurfaceView instead of SurfaceTexture on Android.
const char kForceVideoOverlays[] = "force-video-overlays";

// Allows explicitly specifying MSE audio/video buffer sizes as megabytes.
// Default values are 150M for video and 12M for audio.
const char kMSEAudioBufferSizeLimitMb[] = "mse-audio-buffer-size-limit-mb";
const char kMSEVideoBufferSizeLimitMb[] = "mse-video-buffer-size-limit-mb";

// Specifies the path to the Clear Key CDM for testing, which is necessary to
// support External Clear Key key system when library CDM is enabled. Note that
// External Clear Key key system support is also controlled by feature
// kExternalClearKeyForTesting.
const char kClearKeyCdmPathForTesting[] = "clear-key-cdm-path-for-testing";

// Overrides the default enabled library CDM interface version(s) with the one
// specified with this switch, which will be the only version enabled. For
// example, on a build where CDM 8, CDM 9 and CDM 10 are all supported
// (implemented), but only CDM 8 and CDM 9 are enabled by default:
//  --override-enabled-cdm-interface-version=8 : Only CDM 8 is enabled
//  --override-enabled-cdm-interface-version=9 : Only CDM 9 is enabled
//  --override-enabled-cdm-interface-version=10 : Only CDM 10 is enabled
//  --override-enabled-cdm-interface-version=11 : No CDM interface is enabled
// This can be used for local testing and debugging. It can also be used to
// enable an experimental CDM interface (which is always disabled by default)
// for testing while it's still in development.
const char kOverrideEnabledCdmInterfaceVersion[] =
    "override-enabled-cdm-interface-version";

// Overrides hardware secure codecs support for testing. If specified, real
// platform hardware secure codecs check will be skipped. Valid codecs are:
// - video: "vp8", "vp9", "avc1", "hevc", "dolbyvision", "av01"
// - video that does not support clear lead: `<video>-no-clearlead`, where
//   <video> is from the list above.
// - audio: "mp4a", "vorbis"
// Codecs are separated by comma. For example:
//  --override-hardware-secure-codecs-for-testing=vp8,vp9-no-clearlead,vorbis
//  --override-hardware-secure-codecs-for-testing=avc1,mp4a
// CENC encryption scheme is assumed to be supported for the specified codecs.
// If no valid codecs specified, no hardware secure codecs are supported. This
// can be used to disable hardware secure codecs support:
//  --override-hardware-secure-codecs-for-testing
const char kOverrideHardwareSecureCodecsForTesting[] =
    "override-hardware-secure-codecs-for-testing";

// Sets the default value for the kLiveCaptionEnabled preference to true.
const char kEnableLiveCaptionPrefForTesting[] =
    "enable-live-caption-pref-for-testing";

#if BUILDFLAG(IS_CHROMEOS)
// These are flags passed from ash-chrome to lacros-chrome that correspond to
// buildflags for the platform we are running on. lacros-chrome only builds for
// x86/arm differences, so we unconditionally build in the below features into
// the relevant parts of lacros-chrome and then filter the functionality based
// on these command line flags.
MEDIA_EXPORT extern const char kLacrosEnablePlatformHevc[] =
    "lacros-enable-platform-hevc";
MEDIA_EXPORT extern const char kLacrosUseChromeosProtectedMedia[] =
    "lacros-use-chromeos-protected-media";
MEDIA_EXPORT extern const char kLacrosUseChromeosProtectedAv1[] =
    "lacros-use-chromeos-protected-av1";
#endif  // BUILDFLAG(IS_CHROMEOS)

namespace autoplay {

// Autoplay policy that requires a document user activation.
const char kDocumentUserActivationRequiredPolicy[] =
    "document-user-activation-required";

// Autoplay policy that does not require any user gesture.
const char kNoUserGestureRequiredPolicy[] = "no-user-gesture-required";

// Autoplay policy to require a user gesture in order to play.
const char kUserGestureRequiredPolicy[] = "user-gesture-required";

}  // namespace autoplay

#if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
// Some (Qualcomm only at the moment) V4L2 video decoders require setting the
// framerate so that the hardware decoder can scale the clocks efficiently.
// This provides a mechanism during testing to lock the decoder framerate
// to a specific value.
const char kHardwareVideoDecodeFrameRate[] = "hardware-video-decode-framerate";
// Set the task runner strategy used for hardware video decoding on ChromeOS.
// If the option value of --chromeos-decoder-task-runner is
// * OneThreadPoolSequenceSharedByAllDecoders, then SequencedTaskRunner.
// * OneThreadPoolThreadSharedByAllDecoders, then SingleThreadTaskRunner
//   (one of the threads in ThreadPool).
// * OneDedicatedThreadSharedByAllDecoders, then SingleThreadTaskRunner of
//   base::Thread("VDdecThread"), which is unique and only used for video
//   decoders.
// * OneThreadPoolThreadPerDecoder (default), then SingleThreadTaskRunner
//   of a dedicated thread newly created in ThreadPool per decoder.
// TODO(b/195769334): Propagate this to Chrome utility process for
// Out-of-Process video decoding.
const char kChromeOSVideoDecoderTaskRunner[] =
    "chromeos-video-decoder-task-runner";
#endif

const char kCastStreamingForceDisableHardwareH264[] =
    "cast-streaming-force-disable-hardware-h264";
const char kCastStreamingForceDisableHardwareVp8[] =
    "cast-streaming-force-disable-hardware-vp8";
const char kCastStreamingForceEnableHardwareH264[] =
    "cast-streaming-force-enable-hardware-h264";
const char kCastStreamingForceEnableHardwareVp8[] =
    "cast-streaming-force-enable-hardware-vp8";

// Disables the code path that makes Pepper use the MojoVideoDecoder for
// hardware accelerated video decoding. It overrides the value of the
// kUseMojoVideoDecoderForPepper feature flag.
const char kDisableUseMojoVideoDecoderForPepper[] =
    "disable-use-mojo-video-decoder-for-pepper";

}  // namespace switches

namespace media {

// Enables customized AudioRendererAlgorithmParameters.
BASE_FEATURE(kAudioRendererAlgorithmParameters,
             "AudioRendererAlgorithmParameters",
             base::FEATURE_DISABLED_BY_DEFAULT);

const base::FeatureParam<base::TimeDelta>
    kAudioRendererAlgorithmStartingCapacityForEncrypted{
        &kAudioRendererAlgorithmParameters, "starting_capacity_for_encrypted",
        base::Milliseconds(500)};

// Prefer FFmpeg to LibVPX for Vp8 decoding with opaque alpha mode.
BASE_FEATURE(kFFmpegDecodeOpaqueVP8,
             "FFmpegDecodeOpaqueVP8",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Only used for disabling overlay fullscreen (aka SurfaceView) in Clank.
BASE_FEATURE(kOverlayFullscreenVideo,
             "overlay-fullscreen-video",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Pauses muted (and uncaptured) playbacks in the background.
BASE_FEATURE(kPauseBackgroundMutedAudio,
             "PauseBackgroundMutedAudio",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enables user control over muting tab audio from the tab strip.
BASE_FEATURE(kEnableTabMuting,
             "EnableTabMuting",
             base::FEATURE_DISABLED_BY_DEFAULT);

#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
// Enables HEVC hardware accelerated decoding.
BASE_FEATURE(kPlatformHEVCDecoderSupport,
             "PlatformHEVCDecoderSupport",
             base::FEATURE_ENABLED_BY_DEFAULT);

#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
// Enables HEVC hardware accelerated encoding for Windows and Mac.
BASE_FEATURE(kPlatformHEVCEncoderSupport,
             "PlatformHEVCEncoderSupport",
             base::FEATURE_DISABLED_BY_DEFAULT);
#endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)

// Only decode preload=metadata elements upon visibility.
// TODO(crbug.com/879406): Remove this after M76 ships to stable
BASE_FEATURE(kPreloadMetadataLazyLoad,
             "PreloadMetadataLazyLoad",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Let videos be resumed via remote controls (for example, the notification)
// when in background.
BASE_FEATURE(kResumeBackgroundVideo,
             "resume-background-video",
#if BUILDFLAG(IS_ANDROID) || (BUILDFLAG(IS_OHOS) && defined(OHOS_MEDIA))
             base::FEATURE_ENABLED_BY_DEFAULT
#else
             base::FEATURE_DISABLED_BY_DEFAULT
#endif
);

// When enabled, MediaCapabilities will check with GPU Video Accelerator
// Factories to determine isPowerEfficient = true/false.
BASE_FEATURE(kMediaCapabilitiesQueryGpuFactories,
             "MediaCapabilitiesQueryGpuFactories",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enable Media Capabilities with finch-parameters.
BASE_FEATURE(kMediaCapabilitiesWithParameters,
             "MediaCapabilitiesWithParameters",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Used to set a few tunable parameters for the WebRTC Media Capabilities
// implementation.
BASE_FEATURE(kWebrtcMediaCapabilitiesParameters,
             "WebrtcMediaCapabilitiesParameters",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Display the Cast overlay button on the media controls.
BASE_FEATURE(kMediaCastOverlayButton,
             "MediaCastOverlayButton",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Use AndroidOverlay only if required for secure video playback. This requires
// that |kOverlayFullscreenVideo| is true, else it is ignored.
BASE_FEATURE(kUseAndroidOverlayForSecureOnly,
             "UseAndroidOverlayForSecureOnly",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Allows usage of OS-level (platform) audio encoders.
BASE_FEATURE(kPlatformAudioEncoder,
             "PlatformAudioEncoder",
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
             base::FEATURE_ENABLED_BY_DEFAULT
#else
             base::FEATURE_DISABLED_BY_DEFAULT
#endif
);

// If enabled, RTCVideoDecoderAdapter will wrap a DecoderStream as a video
// decoder, rather than using MojoVideoDecoder.  This causes the RTC external
// decoder to have all the decoder selection / fallback/forward logic of the
// non-RTC pipeline.
// TODO(liberato): This also causes the external decoder to use software
// decoding sometimes, which changes the interpretation of "ExternalDecoder".
BASE_FEATURE(kUseDecoderStreamForWebRTC,
             "UseDecoderStreamForWebRTC",
             base::FEATURE_DISABLED_BY_DEFAULT);

// If enabled, when RTCVideoDecoderAdapter is used then SW decoders will be
// exposed directly to WebRTC.
BASE_FEATURE(kExposeSwDecodersToWebRTC,
             "ExposeSwDecodersToWebRTC",
             base::FEATURE_DISABLED_BY_DEFAULT);

// CDM host verification is enabled by default. Can be disabled for testing.
// Has no effect if ENABLE_CDM_HOST_VERIFICATION buildflag is false.
BASE_FEATURE(kCdmHostVerification,
             "CdmHostVerification",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Use per-CDM-type, per-user and per-site CDM processes (for library CDM). If
// disabled, the CDM processes are only per-CDM-type, meaning different sites
// using the same CDM type would share one CDM process.
BASE_FEATURE(kCdmProcessSiteIsolation,
             "CdmProcessSiteIsolation",
             base::FEATURE_ENABLED_BY_DEFAULT);

#if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
// If echo cancellation for a mic signal is requested, mix and cancel all audio
// playback going to a specific output device in the audio service.
BASE_FEATURE(kChromeWideEchoCancellation,
             "ChromeWideEchoCancellation",
#if BUILDFLAG(IS_CHROMEOS_DEVICE)
    base::FEATURE_DISABLED_BY_DEFAULT
#else
    base::FEATURE_ENABLED_BY_DEFAULT
#endif
             );

// When audio processing is done in the audio process, at the renderer side IPC
// is set up to receive audio at the processing sample rate. This is a
// kill-switch to fallback to receiving audio at the default sample rate of the
// audio capture device.
const base::FeatureParam<bool> kChromeWideEchoCancellationMinimizeResampling{
    &kChromeWideEchoCancellation, "minimize_resampling", true};

// Dynamically sets audio::SyncReader's timeout based off of a percentage of
// buffer duration, in an attempt to minimize glitches.
// The default negative value indicates that no experiment is running, and
// we shouldn't use a mixing specific timeout value.
// If the similar kDynamicAudioTimeout feature is enabled and this value is set,
// this parameter will override kDynamicAudioTimeout values when we are mixing.
const base::FeatureParam<double>
    kChromeWideEchoCancellationDynamicMixingTimeout{
        &kChromeWideEchoCancellation, "mixing_buffer_duration_percent", -1.0};

// Allows all sample rates to be used for audio processing. If disabled, only
// sample rates divisible by 100 are allowed; a request for a media stream with
// enabled audio processing will fail otherwise. For context see
// https://crbug.com/1332484.
const base::FeatureParam<bool> kChromeWideEchoCancellationAllowAllSampleRates{
    &kChromeWideEchoCancellation, "allow_all_sample_rates", true};

// https://crbug.com/1420568
// Applicable only if kChromeWideEchoCancellation is enabled.
// If disabled, the ProcessingAudioFifo size defaults to 110.
// If enabled, the ProcessingAudioFifo size is set to the value of the fifo_size
// parameter.
//
// If the ProcessingAudioFifo size is non-zero, audio processing is done on a
// dedicated processing thread which receives audio from the audio capture
// thread via a fifo of a specified size.
// If the ProcessingAudioFifo size is zero, the usage of this processing thread
// is disabled and processing is done on the audio capture thread itself.
BASE_FEATURE(kDecreaseProcessingAudioFifoSize,
             "DecreaseProcessingAudioFifoSize",
             base::FEATURE_DISABLED_BY_DEFAULT);

const base::FeatureParam<int> kDecreaseProcessingAudioFifoSizeValue{
    &kDecreaseProcessingAudioFifoSize, "fifo_size",
    110  // Default value for the enabled feature.
};

#endif

#if BUILDFLAG(IS_CHROMEOS)
// To control running audio communication effect on Chrome OS Audio Server.
BASE_FEATURE(kCrOSSystemAEC,
             "CrOSSystemAECWithBoardTuningsAllowed",
             base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kCrOSSystemAECDeactivatedGroups,
             "CrOSSystemAECDeactivatedGroups",
             base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kCrOSEnforceSystemAecNsAgc,
             "CrOSEnforceSystemAecNsAgc",
             base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kCrOSEnforceSystemAecNs,
             "CrOSEnforceSystemAecNs",
             base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kCrOSEnforceSystemAecAgc,
             "CrOSEnforceSystemAecAgc",
             base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kCrOSEnforceSystemAec,
             "CrOSEnforceSystemAec",
             base::FEATURE_DISABLED_BY_DEFAULT);

BASE_FEATURE(kCrOSDspBasedAecDeactivatedGroups,
             "CrOSDspBasedAecDeactivatedGroups",
             base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kCrOSDspBasedNsDeactivatedGroups,
             "CrOSDspBasedNsDeactivatedGroups",
             base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kCrOSDspBasedAgcDeactivatedGroups,
             "CrOSDspBasedAgcDeactivatedGroups",
             base::FEATURE_ENABLED_BY_DEFAULT);

BASE_FEATURE(kCrOSDspBasedAecAllowed,
             "CrOSDspBasedAecAllowed",
             base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kCrOSDspBasedNsAllowed,
             "CrOSDspBasedNsAllowed",
             base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kCrOSDspBasedAgcAllowed,
             "CrOSDspBasedAgcAllowed",
             base::FEATURE_ENABLED_BY_DEFAULT);
#endif

// Make MSE garbage collection algorithm more aggressive when we are under
// moderate or critical memory pressure. This will relieve memory pressure by
// releasing stale data from MSE buffers.
BASE_FEATURE(kMemoryPressureBasedSourceBufferGC,
             "MemoryPressureBasedSourceBufferGC",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enables creating single shared image and mailbox for multi-planar formats for
// hardware video decoders.
BASE_FEATURE(kUseMultiPlaneFormatForHardwareVideo,
             "UseMultiPlaneFormatForHardwareVideo",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enables creating single shared image and mailbox for multi-planar formats for
// software video decoders.
BASE_FEATURE(kUseMultiPlaneFormatForSoftwareVideo,
             "UseMultiPlaneFormatForSoftwareVideo",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enables binding software video NV12/P010 GMBs as separate shared images.
BASE_FEATURE(kMultiPlaneSoftwareVideoSharedImages,
             "MultiPlaneSoftwareVideoSharedImages",
#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN)
             base::FEATURE_ENABLED_BY_DEFAULT
#else
             base::FEATURE_DISABLED_BY_DEFAULT
#endif
);

// Enable binding multiple shared images to a single GpuMemoryBuffer for video
// frames created by video capture.
BASE_FEATURE(kMultiPlaneVideoCaptureSharedImages,
             "MultiPlaneVideoCaptureSharedImages",
#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN)
             base::FEATURE_ENABLED_BY_DEFAULT
#else
             base::FEATURE_DISABLED_BY_DEFAULT
#endif
);

// Controls whether the Open Screen libcast SenderSession is used for
// initializing and managing streaming sessions, or the legacy implementation.
BASE_FEATURE(kOpenscreenCastStreamingSession,
             "OpenscreenCastStreamingSession",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Controls whether the Mirroring Service will fetch, analyze, and store
// information on the quality of the session using RTCP logs.
BASE_FEATURE(kEnableRtcpReporting,
             "EnableRtcpReporting",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Approach original pre-REC MSE object URL autorevoking behavior, though await
// actual attempt to use the object URL for attachment to perform revocation.
// This will hopefully reduce runtime memory bloat for pages that do not
// explicitly detach their HTMLME+MSE object collections nor explicitly revoke
// the object URLs used to attach HTMLME+MSE. When disabled, revocation only
// occurs when application explicitly revokes the object URL, or upon the
// execution context teardown for the MediaSource object. When enabled,
// revocation occurs upon successful start of attachment of HTMLME to the object
// URL. Note, rather than immediately scheduling a task to revoke upon the URL's
// creation, as at least one other browser does and the original File API
// pattern used to follow, this delay until attachment start enables new
// scenarios that could use the object URL for attaching HTMLME+MSE cross-thread
// (MSE-in-workers), where there could be significant delay between the worker
// thread creation of the object URL and the main thread usage of the object URL
// for starting attachment to HTMLME.
BASE_FEATURE(kRevokeMediaSourceObjectURLOnAttach,
             "RevokeMediaSourceObjectURLOnAttach",
             base::FEATURE_ENABLED_BY_DEFAULT);

BASE_FEATURE(kD3D11VideoDecoderUseSharedHandle,
             "D3D11VideoDecoderUseSharedHandle",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Runs the media service in the GPU process on a dedicated thread.
BASE_FEATURE(kDedicatedMediaServiceThread,
             "DedicatedMediaServiceThread",
#if BUILDFLAG(IS_WIN)
             base::FEATURE_DISABLED_BY_DEFAULT
#else
             base::FEATURE_ENABLED_BY_DEFAULT
#endif
);

// Falls back to other decoders after audio/video decode error happens. The
// implementation may choose different strategies on when to fallback. See
// DecoderStream for details. When disabled, playback will fail immediately
// after a decode error happens. This can be useful in debugging and testing
// because the behavior is simpler and more predictable.
BASE_FEATURE(kFallbackAfterDecodeError,
             "FallbackAfterDecodeError",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Show toolbar button that opens dialog for controlling media sessions.
BASE_FEATURE(kGlobalMediaControls,
             "GlobalMediaControls",
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
             base::FEATURE_ENABLED_BY_DEFAULT
#else
             base::FEATURE_DISABLED_BY_DEFAULT
#endif
);

// Auto-dismiss global media controls.
BASE_FEATURE(kGlobalMediaControlsAutoDismiss,
             "GlobalMediaControlsAutoDismiss",
             base::FEATURE_ENABLED_BY_DEFAULT);

#if BUILDFLAG(IS_CHROMEOS)
// Updated global media controls UI for CrOS.
BASE_FEATURE(kGlobalMediaControlsCrOSUpdatedUI,
             "GlobalMediaControlsCrOSUpdatedUI",
             base::FEATURE_DISABLED_BY_DEFAULT);
#endif

#if !BUILDFLAG(IS_ANDROID)
// If enabled, users can request Media Remoting without fullscreen-in-tab.
BASE_FEATURE(kMediaRemotingWithoutFullscreen,
             "MediaRemotingWithoutFullscreen",
             base::FEATURE_DISABLED_BY_DEFAULT);
#endif

// Allow Global Media Controls in system tray of CrOS.
BASE_FEATURE(kGlobalMediaControlsForChromeOS,
             "GlobalMediaControlsForChromeOS",
             base::FEATURE_ENABLED_BY_DEFAULT);

constexpr base::FeatureParam<kCrosGlobalMediaControlsPinOptions>::Option
    kCrosGlobalMediaControlsParamOptions[] = {
        {kCrosGlobalMediaControlsPinOptions::kPin, "default-pinned"},
        {kCrosGlobalMediaControlsPinOptions::kNotPin, "default-unpinned"},
        {kCrosGlobalMediaControlsPinOptions::kHeuristic, "heuristic"}};

constexpr base::FeatureParam<kCrosGlobalMediaControlsPinOptions>
    kCrosGlobalMediaControlsPinParam(
        &kGlobalMediaControlsForChromeOS,
        "CrosGlobalMediaControlsPinParam",
        kCrosGlobalMediaControlsPinOptions::kHeuristic,
        &kCrosGlobalMediaControlsParamOptions);

// Show picture-in-picture button in Global Media Controls.
BASE_FEATURE(kGlobalMediaControlsPictureInPicture,
             "GlobalMediaControlsPictureInPicture",
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
    BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_CHROMEOS_LACROS)
             base::FEATURE_ENABLED_BY_DEFAULT
#else
             base::FEATURE_DISABLED_BY_DEFAULT
#endif
);

// Enable selection of audio output device in Global Media Controls.
BASE_FEATURE(kGlobalMediaControlsSeamlessTransfer,
             "GlobalMediaControlsSeamlessTransfer",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enable an updated version of the Global Media Controls UI.
BASE_FEATURE(kGlobalMediaControlsModernUI,
             "GlobalMediaControlsModernUI",
             base::FEATURE_DISABLED_BY_DEFAULT);

// CanPlayThrough issued according to standard.
BASE_FEATURE(kSpecCompliantCanPlayThrough,
             "SpecCompliantCanPlayThrough",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Disables the real audio output stream after silent audio has been delivered
// for too long. Should save quite a bit of power in the muted video case.
BASE_FEATURE(kSuspendMutedAudio,
             "SuspendMutedAudio",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enables using the media history store to store media engagement metrics.
BASE_FEATURE(kUseMediaHistoryStore,
             "UseMediaHistoryStore",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Use R16 texture for 9-16 bit channel instead of half-float conversion by CPU.
BASE_FEATURE(kUseR16Texture,
             "use-r16-texture",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enables the Unified Autoplay policy by overriding the platform's default
// autoplay policy.
BASE_FEATURE(kUnifiedAutoplay,
             "UnifiedAutoplay",
             base::FEATURE_ENABLED_BY_DEFAULT);

#if BUILDFLAG(IS_LINUX)
// Enable vaapi video decoding on linux. This is already enabled by default on
// chromeos, but needs an experiment on linux.
BASE_FEATURE(kVaapiVideoDecodeLinux,
             "VaapiVideoDecoder",
             base::FEATURE_ENABLED_BY_DEFAULT);

BASE_FEATURE(kVaapiVideoDecodeLinuxGL,
             "VaapiVideoDecodeLinuxGL",
             base::FEATURE_DISABLED_BY_DEFAULT);

BASE_FEATURE(kVaapiVideoEncodeLinux,
             "VaapiVideoEncoder",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Ignore the non-intel driver blacklist for VaapiVideoDecoder implementations.
// Intended for manual usage only in order to gague the status of newer driver
// implementations.
BASE_FEATURE(kVaapiIgnoreDriverChecks,
             "VaapiIgnoreDriverChecks",
             base::FEATURE_DISABLED_BY_DEFAULT);
#endif  // BUILDFLAG(IS_LINUX)

// Enable VA-API hardware low power encoder for all codecs on intel Gen9x gpu.
BASE_FEATURE(kVaapiLowPowerEncoderGen9x,
             "VaapiLowPowerEncoderGen9x",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Reject creation of encode/decode VAContexts when the requested resolution is
// outside the enumerated minimum and maximum. TODO(b/171041334): Remove and
// enable by default once the ARC++ hw codecs issue is fixed.
BASE_FEATURE(kVaapiEnforceVideoMinMaxResolution,
             "VaapiEnforceVideoMinMaxResolution",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Ensure the advertised minimum supported resolution is larger than or equal to
// a given one (likely QVGA + 1) for certain codecs/modes and platforms, for
// performance reasons. This does not affect JPEG decoding.
BASE_FEATURE(kVaapiVideoMinResolutionForPerformance,
             "VaapiVideoMinResolutionForPerformance",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enable VA-API hardware encode acceleration for VP8.
BASE_FEATURE(kVaapiVP8Encoder,
             "VaapiVP8Encoder",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enable VA-API hardware encode acceleration for VP9.
BASE_FEATURE(kVaapiVP9Encoder,
             "VaapiVP9Encoder",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enable VA-API hardware encode acceleration for AV1.
BASE_FEATURE(kVaapiAV1Encoder,
             "VaapiAV1Encoder",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enable global VA-API lock. Disable this to use lock-free VA-API function
// calls for thread safe backends.
BASE_FEATURE(kGlobalVaapiLock,
             "GlobalVaapiLock",
             base::FEATURE_ENABLED_BY_DEFAULT);

#if defined(ARCH_CPU_X86_FAMILY) && BUILDFLAG(IS_CHROMEOS)
// TODO(b/214589754): revisit the need for the BUILDFLAG(IS_CHROMEOS) guard (as
// opposed to BUILDFLAG(IS_CHROMEOS_ASH)) when the final design for HW
// encoding is implemented for lacros-chrome.
// Enable H264 temporal layer encoding with HW encoder on ChromeOS.
BASE_FEATURE(kVaapiH264TemporalLayerHWEncoding,
             "VaapiH264TemporalLayerEncoding",
             base::FEATURE_ENABLED_BY_DEFAULT);
// Enable VP8 temporal layer encoding with HW encoder on ChromeOS.
BASE_FEATURE(kVaapiVp8TemporalLayerHWEncoding,
             "VaapiVp8TemporalLayerEncoding",
             base::FEATURE_DISABLED_BY_DEFAULT);
// Enable VP9 k-SVC encoding with HW encoder for webrtc use case on ChromeOS.
BASE_FEATURE(kVaapiVp9kSVCHWEncoding,
             "VaapiVp9kSVCHWEncoding",
             base::FEATURE_ENABLED_BY_DEFAULT);
#endif  // defined(ARCH_CPU_X86_FAMILY) && BUILDFLAG(IS_CHROMEOS)

// Inform video blitter of video color space.
BASE_FEATURE(kVideoBlitColorAccuracy,
             "video-blit-color-accuracy",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enable VP9 k-SVC decoding with HW decoder for webrtc use case.
BASE_FEATURE(kVp9kSVCHWDecoding,
             "Vp9kSVCHWDecoding",
#if BUILDFLAG(IS_CHROMEOS)
             base::FEATURE_ENABLED_BY_DEFAULT
#else
             base::FEATURE_DISABLED_BY_DEFAULT
#endif
);

// Takes a reference on a video frame, keeping it alive during the duration of a
// video.requestVideoFrameCallback call. Doesn't change anything to the API for
// now, as this is only used to measure the potential impact of keeping frames
// alive for longer. See crbug.com/1259784.
BASE_FEATURE(kKeepRvfcFrameAlive,
             "keep-rvfc-frame-alive",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enables support for External Clear Key (ECK) key system for testing on
// supported platforms. On platforms that do not support ECK, this feature has
// no effect.
BASE_FEATURE(kExternalClearKeyForTesting,
             "ExternalClearKeyForTesting",
             base::FEATURE_DISABLED_BY_DEFAULT);

#if BUILDFLAG(IS_WIN)
// Specifies the path to the MediaFoundation Clear Key CDM for testing.
const base::FeatureParam<std::string> kMediaFoundationClearKeyCdmPathForTesting{
    &kExternalClearKeyForTesting, "media_foundation_cdm_path", ""};
#endif  // BUILDFLAG(IS_WIN)

// Enables the Live Caption feature on supported devices.
BASE_FEATURE(kLiveCaption, "LiveCaption", base::FEATURE_ENABLED_BY_DEFAULT);

// Controls whether a "Share this tab instead" button should be shown for
// getDisplayMedia captures. Note: This flag does not control if the "Share this
// tab instead" button is shown for chrome.desktopCapture captures.
BASE_FEATURE(kShareThisTabInsteadButtonGetDisplayMedia,
             "ShareThisTabInsteadButtonGetDisplayMedia",
             base::FEATURE_ENABLED_BY_DEFAULT);

// If kShareThisTabInsteadButtonGetDisplayMedia is ENABLED, this flag controls
// whether a "Share this tab instead" button should be enabled for
// getDisplayMedia captures with audio.
// If kShareThisTabInsteadButtonGetDisplayMedia is DISABLED, this flag has no
// effect.
// Note: This flag does not control if the "Share this tab instead" button is
// shown for chrome.desktopCapture captures.
BASE_FEATURE(kShareThisTabInsteadButtonGetDisplayMediaAudio,
             "ShareThisTabInsteadButtonGetDisplayMediaAudio",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enable the Speaker Change Detection feature, which inserts a line break when
// the Speech On-Device API (SODA) detects a speaker change.
BASE_FEATURE(kSpeakerChangeDetection,
             "SpeakerChangeDetection",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Live Caption can be used in multiple languages, as opposed to just English.
BASE_FEATURE(kLiveCaptionMultiLanguage,
             "LiveCaptionMultiLanguage",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enable or disable Live Caption from the right click menu.
BASE_FEATURE(kLiveCaptionRightClick,
             "LiveCaptionRightClick",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Live Caption runs system-wide on ChromeOS, as opposed to just in the browser.
BASE_FEATURE(kLiveCaptionSystemWideOnChromeOS,
             "LiveCaptionSystemWideOnChromeOS",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Live Translate translates captions generated by Live Caption.
BASE_FEATURE(kLiveTranslate,
             "LiveTranslate",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Prevents UrlProvisionFetcher from making a provisioning request. If
// specified, any provisioning request made will not be sent to the provisioning
// server, and the response will indicate a failure to communicate with the
// provisioning server.
BASE_FEATURE(kFailUrlProvisionFetcherForTesting,
             "FailUrlProvisionFetcherForTesting",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enables hardware secure decryption if supported by hardware and CDM.
// TODO(xhwang): Currently this is only used for development of new features.
// Apply this to Android and ChromeOS as well where hardware secure decryption
// is already available.
BASE_FEATURE(kHardwareSecureDecryption,
             "HardwareSecureDecryption",
             base::FEATURE_DISABLED_BY_DEFAULT);

// By default, a codec is not supported for hardware secure decryption if it
// does not support clear lead. This option forces the support for testing.
const base::FeatureParam<bool> kHardwareSecureDecryptionForceSupportClearLead{
    &kHardwareSecureDecryption, "force_support_clear_lead", false};

// Same as `kHardwareSecureDecryption` above, but only enable experimental
// sub key systems. Which sub key system is experimental is key system specific.
BASE_FEATURE(kHardwareSecureDecryptionExperiment,
             "HardwareSecureDecryptionExperiment",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Allows automatically disabling hardware secure Content Decryption Module
// (CDM) after failures or crashes to fallback to software secure CDMs. If this
// feature is disabled, the fallback will never happen and users could be stuck
// in playback failures.
BASE_FEATURE(kHardwareSecureDecryptionFallback,
             "HardwareSecureDecryptionFallback",
             base::FEATURE_ENABLED_BY_DEFAULT);

// The minimum and maximum number of days to disable hardware secure Content
// Decryption Module (CDM) as part of the fallback logic.
const base::FeatureParam<int> kHardwareSecureDecryptionFallbackMinDisablingDays{
    &kHardwareSecureDecryptionFallback, "min_disabling_days", 30};
const base::FeatureParam<int> kHardwareSecureDecryptionFallbackMaxDisablingDays{
    &kHardwareSecureDecryptionFallback, "max_disabling_days", 180};

// Whether selected HardwareContextReset events should be considered as failures
// in the hardware secure decryption fallback logic.
const base::FeatureParam<bool>
    kHardwareSecureDecryptionFallbackOnHardwareContextReset{
        &kHardwareSecureDecryptionFallback, "on_hardware_context_reset", true};

// If active, enable HiDPI mode that increases the display scale factor
// while capturing a low-resolution tab.
BASE_FEATURE(kWebContentsCaptureHiDpi,
             "WebContentsCaptureHiDPI",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enables handling of hardware media keys for controlling media.
BASE_FEATURE(kHardwareMediaKeyHandling,
             "HardwareMediaKeyHandling",
#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
    BUILDFLAG(USE_MPRIS)
             base::FEATURE_ENABLED_BY_DEFAULT
#else
             base::FEATURE_DISABLED_BY_DEFAULT
#endif
);

// Enables a platform-specific resolution cutoff for prioritizing platform
// decoders over software decoders or vice-versa.
BASE_FEATURE(kResolutionBasedDecoderPriority,
             "ResolutionBasedDecoderPriority",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Forces use of hardware (platform) video decoders in
// `media::DecoderSelector`.
BASE_FEATURE(kForceHardwareVideoDecoders,
             "ForceHardwareVideoDecoders",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Forces use of hardware (platform) audio decoders in
// `media::DecoderSelector`.
BASE_FEATURE(kForceHardwareAudioDecoders,
             "ForceHardwareAudioDecoders",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enables low-delay video rendering in media pipeline on "live" stream.
BASE_FEATURE(kLowDelayVideoRenderingOnLiveStream,
             "low-delay-video-rendering-on-live-stream",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Whether the autoplay policy should ignore Web Audio. When ignored, the
// autoplay policy will be hardcoded to be the legacy one on based on the
// platform
BASE_FEATURE(kAutoplayIgnoreWebAudio,
             "AutoplayIgnoreWebAudio",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Whether we should show a setting to disable autoplay policy.
BASE_FEATURE(kAutoplayDisableSettings,
             "AutoplayDisableSettings",
             base::FEATURE_DISABLED_BY_DEFAULT);

#if BUILDFLAG(IS_ANDROID)
// Should we allow video playback to use an overlay if it's not needed for
// security?  Normally, we'd always want to allow this, except as part of the
// power testing A/B experiment.  https://crbug.com/1081346 .
BASE_FEATURE(kAllowNonSecureOverlays,
             "AllowNonSecureOverlays",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enable a gesture to make the media controls expaned into the display cutout.
// TODO(beccahughes): Remove this.
BASE_FEATURE(kMediaControlsExpandGesture,
             "MediaControlsExpandGesture",
             base::FEATURE_ENABLED_BY_DEFAULT);

// An experimental feature to enable persistent-license type support in MediaDrm
// when using Encrypted Media Extensions (EME) API.
// TODO(xhwang): Remove this after feature launch. See http://crbug.com/493521
BASE_FEATURE(kMediaDrmPersistentLicense,
             "MediaDrmPersistentLicense",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enables MediaDrmOriginIdManager to provide preprovisioned origin IDs for
// MediaDrmBridge. If disabled, MediaDrmBridge will get unprovisioned origin IDs
// which will trigger provisioning process after MediaDrmBridge is created.
BASE_FEATURE(kMediaDrmPreprovisioning,
             "MediaDrmPreprovisioning",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Determines if MediaDrmOriginIdManager should attempt to pre-provision origin
// IDs at startup (whenever a profile is loaded). Also used by tests that
// disable it so that the tests can setup before pre-provisioning is done.
// Note: Has no effect if kMediaDrmPreprovisioning feature is disabled.
BASE_FEATURE(kMediaDrmPreprovisioningAtStartup,
             "MediaDrmPreprovisioningAtStartup",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enables CanPlayType() (and other queries) for HLS MIME types. Note that
// disabling this also causes navigation to .m3u8 files to trigger downloading
// instead of playback.
BASE_FEATURE(kCanPlayHls, "CanPlayHls", base::FEATURE_ENABLED_BY_DEFAULT);

// Enables the use of MediaPlayerRenderer for HLS playback. When disabled,
// HLS manifests will fail to load (triggering source fallback or load error).
BASE_FEATURE(kHlsPlayer, "HlsPlayer", base::FEATURE_ENABLED_BY_DEFAULT);

// When enabled, Playing media sessions will request audio focus from the
// Android system.
BASE_FEATURE(kRequestSystemAudioFocus,
             "RequestSystemAudioFocus",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Use the (hacky) AudioManager.getOutputLatency() call to get the estimated
// hardware latency for a stream for OpenSLES playback.  This is normally not
// needed, except for some Android TV devices.
BASE_FEATURE(kUseAudioLatencyFromHAL,
             "UseAudioLatencyFromHAL",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enable pooling of SharedImageVideo objects for use by MCVD, to save a hop to
// the GPU main thread during VideoFrame construction.
BASE_FEATURE(kUsePooledSharedImageVideoProvider,
             "UsePooledSharedImageVideoProvider",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Historically we hardcoded sRGB for color space. This flags controls if we
// pass real color space to VideoFrame/SharedImages.
BASE_FEATURE(kUseRealColorSpaceForAndroidVideo,
             "UseRealColorSpaceForAndroidVideo",
             base::FEATURE_ENABLED_BY_DEFAULT);

#endif  // BUILDFLAG(IS_ANDROID)

#if defined(OHOS_MEDIA)
BASE_FEATURE(kCanPlayHls, "CanPlayHls", base::FEATURE_ENABLED_BY_DEFAULT);
#endif

#if BUILDFLAG(ENABLE_HLS_DEMUXER)
BASE_FEATURE(kBuiltInHlsPlayer,
             "BuiltInHlsPlayer",
             base::FEATURE_DISABLED_BY_DEFAULT);
#endif  // BUILDFLAG(ENABLE_HLS_DEMUXER)

#if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
// Enable hardware AV1 decoder on ChromeOS.
BASE_FEATURE(kChromeOSHWAV1Decoder,
             "ChromeOSHWAV1Decoder",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enable Variable Bitrate encoding with hardware accelerated encoders on
// ChromeOS.
BASE_FEATURE(kChromeOSHWVBREncoding,
             "ChromeOSHWVBREncoding",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enable the hardware-accelerated direct video decoder instead of the one
// needing the VdaVideoDecoder adapter. This flag is used mainly as a
// chrome:flag for developers debugging issues as well as to be able to
// experiment with direct VideoDecoder path on Linux Desktop.
// TODO(b/159825227): remove when the direct video decoder is fully launched.
BASE_FEATURE(kUseChromeOSDirectVideoDecoder,
             "UseChromeOSDirectVideoDecoder",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Limit the number of concurrent hardware decoder instances on ChromeOS.
BASE_FEATURE(kLimitConcurrentDecoderInstances,
             "LimitConcurrentDecoderInstances",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Use SequencedTaskRunner for VideoEncodeAccelerator
BASE_FEATURE(kUSeSequencedTaskRunnerForVEA,
             "UseSequencedTaskRunnerForVEA",
             base::FEATURE_DISABLED_BY_DEFAULT);

#if defined(ARCH_CPU_ARM_FAMILY)
// Experimental support for GL based image processing. On some architectures,
// the hardware accelerated video decoder outputs frames in a format not
// understood by the display controller. We usually use LibYUV to convert these
// frames. This flag enables an experimental GL-based conversion method.
BASE_FEATURE(kPreferGLImageProcessor,
             "PreferGLImageProcessor",
             base::FEATURE_DISABLED_BY_DEFAULT);
#endif  // defined(ARCH_CPU_ARM_FAMILY)
#if BUILDFLAG(IS_CHROMEOS)
// ChromeOS has one of two VideoDecoder implementations active based on
// SoC/board specific configurations that are sent via command line flags. This
// switch allows using the non default implementation for testing.
// TODO(b/159825227): remove when the "old" video decoder is fully launched.
BASE_FEATURE(kUseAlternateVideoDecoderImplementation,
             "UseAlternateVideoDecoderImplementation",
             base::FEATURE_DISABLED_BY_DEFAULT);
#endif  // BUILDFLAG(IS_CHROMEOS)
#endif  // BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)

#if BUILDFLAG(IS_WIN)
// Enables DirectShow GetPhotoState implementation
// Created to act as a kill switch by disabling it, in the case of the
// resurgence of https://crbug.com/722038
BASE_FEATURE(kDirectShowGetPhotoState,
             "DirectShowGetPhotoState",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Includes Infrared cameras in the list returned for EnumerateDevices() on
// Windows.
BASE_FEATURE(kIncludeIRCamerasInDeviceEnumeration,
             "IncludeIRCamerasInDeviceEnumeration",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enables software rate controller encoding acceleration for Windows.
const base::Feature MEDIA_EXPORT kMediaFoundationUseSoftwareRateCtrl{
    "MediaFoundationUseSoftwareRateCtrl", base::FEATURE_ENABLED_BY_DEFAULT};

// Enables MediaFoundation based video capture
BASE_FEATURE(kMediaFoundationVideoCapture,
             "MediaFoundationVideoCapture",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enables MediaFoundation based video capture with D3D11
// For feature check of kMediaFoundationD3D11VideoCapture at runtime,
// please use IsMediaFoundationD3D11VideoCaptureEnabled() instead.
BASE_FEATURE(kMediaFoundationD3D11VideoCapture,
             "MediaFoundationD3D11VideoCapture",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enables VP8 decode acceleration for Windows.
const base::Feature MEDIA_EXPORT kMediaFoundationVP8Decoding{
    "MediaFoundationVP8Decoding", base::FEATURE_DISABLED_BY_DEFAULT};

// Enables the use of MediaFoundationRenderer for clear content on supported
// systems.
BASE_FEATURE(kMediaFoundationClearPlayback,
             "MediaFoundationClearPlayback",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Use the AUDCLNT_STREAMOPTIONS_RAW option on WASAPI input audio streams in
// combination with  the IAudioClient2::SetClientProperties() API.
// The audio stream is a 'raw' stream that bypasses all signal processing except
// for endpoint specific, always-on processing in the Audio Processing Object
// (APO), driver, and hardware.
// https://docs.microsoft.com/en-us/windows/win32/api/audioclient/ne-audioclient-audclnt_streamoptions
const base::Feature MEDIA_EXPORT kWasapiRawAudioCapture{
    "WASAPIRawAudioCapture", base::FEATURE_ENABLED_BY_DEFAULT};

// Emulates audio capture timestamps instead of using timestamps from the actual
// audio device.
// See crbug.com/1315231 for more details.
const base::Feature MEDIA_EXPORT kUseFakeAudioCaptureTimestamps{
    "UseFakeAudioCaptureTimestamps", base::FEATURE_DISABLED_BY_DEFAULT};

// Enable VP9 kSVC decoding with HW decoder for webrtc use case on Windows.
BASE_FEATURE(kD3D11Vp9kSVCHWDecoding,
             "D3D11Vp9kSVCHWDecoding",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Controls whether the DXVA video decoder is enabled on Windows.
BASE_FEATURE(kDXVAVideoDecoding,
             "DXVAVideoDecoding",
             base::FEATURE_DISABLED_BY_DEFAULT);

// The Media Foundation Rendering Strategy determines which presentation mode
// Media Foundation Renderer should use for presenting clear content. This
// strategy has no impact for protected content, which must always use Direct
// Composition.
//
// The strategy may be one of the following options:
// 1.) Direct Composition: Media Foundation Renderer will use a Windowsless
//     Swapchain to present directly to a Direct Composition surface.
// 2.) Frame Server: Media Foundation Renderer will produce Video Frames that
//     may be passed through the Chromium video frame rendering pipeline.
// 3.) Dynamic: Media Foundation Renderer may freely switch between Direct
//     Composition & Frame Server mode based on the current operating
//     conditions.
//
// Command line invocation:
// --enable-features=MediaFoundationClearRendering:strategy/direct-composition
// --enable-features=MediaFoundationClearRendering:strategy/frame-server
// --enable-features=MediaFoundationClearRendering:strategy/dynamic
BASE_FEATURE(kMediaFoundationClearRendering,
             "MediaFoundationClearRendering",
             base::FEATURE_ENABLED_BY_DEFAULT);

constexpr base::FeatureParam<MediaFoundationClearRenderingStrategy>::Option
    kMediaFoundationClearRenderingStrategyOptions[] = {
        {MediaFoundationClearRenderingStrategy::kDirectComposition,
         "direct-composition"},
        {MediaFoundationClearRenderingStrategy::kFrameServer, "frame-server"},
        {MediaFoundationClearRenderingStrategy::kDynamic, "dynamic"}};

const base::FeatureParam<MediaFoundationClearRenderingStrategy>
    kMediaFoundationClearRenderingStrategyParam{
        &kMediaFoundationClearRendering, "strategy",
        MediaFoundationClearRenderingStrategy::kDynamic,
        &kMediaFoundationClearRenderingStrategyOptions};

BASE_FEATURE(kMediaFoundationBatchRead,
             "MediaFoundationBatchRead",
             base::FEATURE_DISABLED_BY_DEFAULT);

const base::FeatureParam<int> kBatchReadCount{&kMediaFoundationBatchRead,
                                              "batch_read_count", 1};
#endif  // BUILDFLAG(IS_WIN)

#if BUILDFLAG(ENABLE_PLATFORM_ENCRYPTED_DOLBY_VISION)
// When ENABLE_PLATFORM_ENCRYPTED_DOLBY_VISION is enabled at build time, allow
// the support of encrypted Dolby Vision. Have no effect when
// ENABLE_PLATFORM_ENCRYPTED_DOLBY_VISION is disabled.
BASE_FEATURE(kPlatformEncryptedDolbyVision,
             "PlatformEncryptedDolbyVision",
             base::FEATURE_DISABLED_BY_DEFAULT);

// When ENABLE_PLATFORM_ENCRYPTED_DOLBY_VISION is enabled at build time and
// `kPlatformEncryptedDolbyVision` is enabled at run time, encrypted Dolby
// Vision is allowed in Media Source while clear Dolby Vision is not allowed.
// In this case, this feature allows the support of clear Dolby Vision in Media
// Source, which is useful to work around some JavaScript player limitations.
// Otherwise, this feature has no effect and neither encrypted nor clear Dolby
// Vision is allowed.
BASE_FEATURE(kAllowClearDolbyVisionInMseWhenPlatformEncryptedDvEnabled,
             "AllowClearDolbyVisionInMseWhenPlatformEncryptedDvEnabled",
             base::FEATURE_DISABLED_BY_DEFAULT);
#endif

#if BUILDFLAG(IS_CHROMEOS_ASH)
// Expose the out-of-process video decoding feature from ash-chrome to
// lacros-chrome through the crosapi.
const base::Feature MEDIA_EXPORT kExposeOutOfProcessVideoDecodingToLacros{
    "ExposeOutOfProcessVideoDecodingToLacros",
    base::FEATURE_DISABLED_BY_DEFAULT};
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

#if BUILDFLAG(ALLOW_OOP_VIDEO_DECODER)
// Spawn utility processes to perform hardware decode acceleration instead of
// using the GPU process.
const base::Feature MEDIA_EXPORT kUseOutOfProcessVideoDecoding{
    "UseOutOfProcessVideoDecoding", base::FEATURE_DISABLED_BY_DEFAULT};
#endif  // BUILDFLAG(ALLOW_OOP_VIDEO_DECODER)

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
// Spawn utility processes to perform hardware encode acceleration instead of
// using the GPU process.
const base::Feature MEDIA_EXPORT kUseOutOfProcessVideoEncoding{
    "UseOutOfProcessVideoEncoding", base::FEATURE_DISABLED_BY_DEFAULT};
#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

// Make the PepperVideoDecoderHost use the MojoVideoDecoder to talk to hardware
// decoders instead of using the GpuVideoDecodeAcceleratorHost. Note: this
// doesn't affect the PPB_VideoDecoder_Impl which will continue to use the
// GpuVideoDecodeAcceleratorHost for the PPB_VideoDecoder_Dev interface.
const base::Feature MEDIA_EXPORT kUseMojoVideoDecoderForPepper{
    "UseMojoVideoDecoderForPepper", base::FEATURE_ENABLED_BY_DEFAULT};

// Use SequencedTaskRunner for MediaService.
BASE_FEATURE(kUseSequencedTaskRunnerForMediaService,
             "UseSequencedTaskRunnerForMediaService",
             base::FEATURE_DISABLED_BY_DEFAULT);

// SequencedTaskRunner isn't supported on Windows since the accelerator requires
// a COM STA TaskRunner.
#if !BUILDFLAG(IS_WIN)
// Use SequencedTaskRunner for MojoVideoEncodeAcceleratorProvider.
BASE_FEATURE(kUseSequencedTaskRunnerForMojoVEAProvider,
             "UseSequencedTaskRunnerForMojoVEAProvider",
#if BUILDFLAG(IS_APPLE)
             base::FEATURE_ENABLED_BY_DEFAULT
#else
             base::FEATURE_DISABLED_BY_DEFAULT
#endif
);
#endif  // !BUILDFLAG(IS_WIN)

// Use TaskRunner for each MojoVideoEncodeAcceleratorService. Replaces
// per-accelerator encoding task runner.
BASE_FEATURE(kUseTaskRunnerForMojoVEAService,
             "UseTaskRunnerForMojoVEAService",
#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN)
             base::FEATURE_ENABLED_BY_DEFAULT
#else
             base::FEATURE_DISABLED_BY_DEFAULT
#endif
);

std::string GetEffectiveAutoplayPolicy(const base::CommandLine& command_line) {
  // Return the autoplay policy set in the command line, if any.
  if (command_line.HasSwitch(switches::kAutoplayPolicy))
    return command_line.GetSwitchValueASCII(switches::kAutoplayPolicy);

  if (base::FeatureList::IsEnabled(media::kUnifiedAutoplay))
    return switches::autoplay::kDocumentUserActivationRequiredPolicy;

// The default value is platform dependent.
#if BUILDFLAG(IS_ANDROID)
  return switches::autoplay::kUserGestureRequiredPolicy;
#else
  return switches::autoplay::kNoUserGestureRequiredPolicy;
#endif
}

// Enables Media Engagement Index recording. This data will be used to determine
// when to bypass autoplay policies. This is recorded on all platforms.
BASE_FEATURE(kRecordMediaEngagementScores,
             "RecordMediaEngagementScores",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enables Media Engagement Index recording for Web Audio playbacks.
BASE_FEATURE(kRecordWebAudioEngagement,
             "RecordWebAudioEngagement",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enables reporting "smpteSt2086" HDR Metadata as supported in the
// MediaCapabilities API.
BASE_FEATURE(kSupportSmpteSt2086HdrMetadata,
             "SupportSmpteSt2086HdrMetadata",
             base::FEATURE_DISABLED_BY_DEFAULT);

// The following Media Engagement flags are not enabled on mobile platforms:
// - MediaEngagementBypassAutoplayPolicies: enables the Media Engagement Index
//   data to be esude to override autoplay policies. An origin with a high MEI
//   will be allowed to autoplay.
// - PreloadMediaEngagementData: enables a list of origins to be considered as
//   having a high MEI until there is enough local data to determine the user's
//   preferred behaviour.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
BASE_FEATURE(kMediaEngagementBypassAutoplayPolicies,
             "MediaEngagementBypassAutoplayPolicies",
             base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kPreloadMediaEngagementData,
             "PreloadMediaEngagementData",
             base::FEATURE_DISABLED_BY_DEFAULT);
#else
BASE_FEATURE(kMediaEngagementBypassAutoplayPolicies,
             "MediaEngagementBypassAutoplayPolicies",
             base::FEATURE_ENABLED_BY_DEFAULT);
BASE_FEATURE(kPreloadMediaEngagementData,
             "PreloadMediaEngagementData",
             base::FEATURE_ENABLED_BY_DEFAULT);
#endif

BASE_FEATURE(kMediaEngagementHTTPSOnly,
             "MediaEngagementHTTPSOnly",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enables experimental local learning for media. Used in the context of media
// capabilities only. Adds reporting only; does not change media behavior.
BASE_FEATURE(kMediaLearningExperiment,
             "MediaLearningExperiment",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enables the general purpose media machine learning framework. Adds reporting
// only; does not change media behavior.
BASE_FEATURE(kMediaLearningFramework,
             "MediaLearningFramework",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enables the smoothness prediction experiment.  Requires
// kMediaLearningFramework to be enabled also, else it does nothing.
BASE_FEATURE(kMediaLearningSmoothnessExperiment,
             "MediaLearningSmoothnessExperiment",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enable the prototype global optimization of tuneables via finch.  See
// media/base/tuneable.h for how to create tuneable parameters.
BASE_FEATURE(kMediaOptimizer,
             "JointMediaOptimizer",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enable aggregate power measurement for media playback.
BASE_FEATURE(kMediaPowerExperiment,
             "MediaPowerExperiment",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Enables flash to be ducked by audio focus. This is enabled on Chrome OS which
// has audio focus enabled.
BASE_FEATURE(kAudioFocusDuckFlash,
             "AudioFocusDuckFlash",
#if BUILDFLAG(IS_CHROMEOS_ASH)
             base::FEATURE_ENABLED_BY_DEFAULT
#else
             base::FEATURE_DISABLED_BY_DEFAULT
#endif
);

// Only affects Android. Suspends a media session when audio focus is lost; when
// this setting is disabled, an Android media session will not be suspended when
// Audio focus is lost. This is used by Cast which sometimes needs to drive
// multiple media sessions.
BASE_FEATURE(kAudioFocusLossSuspendMediaSession,
             "AudioFocusMediaSession",
             base::FEATURE_ENABLED_BY_DEFAULT);

// Enables the internal Media Session logic without enabling the Media Session
// service.
BASE_FEATURE(kInternalMediaSession,
             "InternalMediaSession",
#if BUILDFLAG(IS_ANDROID)
             base::FEATURE_ENABLED_BY_DEFAULT
#else
             base::FEATURE_DISABLED_BY_DEFAULT
#endif
);

// Keypress detection which serves as input to noise suppression methods
// in WebRTC clients. This functionality is enabled by default but it can be
// disabled experemantally by using --disable-features=KeyPressMonitoring.
BASE_FEATURE(kKeyPressMonitoring,
             "KeyPressMonitoring",
             base::FEATURE_ENABLED_BY_DEFAULT);

BASE_FEATURE(kUseFakeDeviceForMediaStream,
             "use-fake-device-for-media-stream",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Makes VideoCadenceEstimator use Bresenham-like algorithm for frame cadence
// estimations.
BASE_FEATURE(kBresenhamCadence,
             "BresenhamCadence",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Controls whether mirroring negotiations will include the AV1 codec for video
// encoding.
//
// NOTE: currently only software AV1 encoding is supported.
// TODO(https://crbug.com/1383333): hardware AV1 encoding should be added.
BASE_FEATURE(kCastStreamingAv1,
             "CastStreamingAv1",
             base::FEATURE_DISABLED_BY_DEFAULT);

// Controls whether mirroring negotiations will include the VP9 codec for video
// encoding.
//
// NOTE: currently only software VP9 encoding is supported.
// TODO(https://crbug.com/1311770): hardware VP9 encoding should be added.
BASE_FEATURE(kCastStreamingVp9,
             "CastStreamingVp9",
             base::FEATURE_DISABLED_BY_DEFAULT);

#if BUILDFLAG(IS_FUCHSIA)
// Enables use of Fuchsia's Mediacodec service for encoding.
BASE_FEATURE(kFuchsiaMediacodecVideoEncoder,
             "FuchsiaMediacodecVideoEncoder",
             base::FEATURE_DISABLED_BY_DEFAULT);
#endif  // BUILDFLAG(IS_FUCHSIA)

bool IsChromeWideEchoCancellationEnabled() {
#if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
#if BUILDFLAG(IS_CHROMEOS_DEVICE)
  if (base::FeatureList::IsEnabled(kCrOSEnforceSystemAecNsAgc) ||
      base::FeatureList::IsEnabled(kCrOSEnforceSystemAecNs) ||
      base::FeatureList::IsEnabled(kCrOSEnforceSystemAecAgc) ||
      base::FeatureList::IsEnabled(kCrOSEnforceSystemAec)) {
    return false;
  }
#endif
  return base::FeatureList::IsEnabled(kChromeWideEchoCancellation);
#else
  return false;
#endif
}

int GetProcessingAudioFifoSize() {
#if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
  if (!IsChromeWideEchoCancellationEnabled()) {
    return 0;
  }
  if (base::FeatureList::IsEnabled(media::kDecreaseProcessingAudioFifoSize)) {
    return media::kDecreaseProcessingAudioFifoSizeValue.Get();
  }
  return 110;
#else
  return 0;
#endif
}

bool IsHardwareSecureDecryptionEnabled() {
  return base::FeatureList::IsEnabled(kHardwareSecureDecryption) ||
         base::FeatureList::IsEnabled(kHardwareSecureDecryptionExperiment);
}

bool IsVideoCaptureAcceleratedJpegDecodingEnabled() {
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kDisableAcceleratedMjpegDecode)) {
    return false;
  }
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kUseFakeMjpegDecodeAccelerator)) {
    return true;
  }
#if BUILDFLAG(IS_CHROMEOS_ASH)
  return true;
#else
  return false;
#endif
}

bool IsMultiPlaneFormatForHardwareVideoEnabled() {
  return base::FeatureList::IsEnabled(features::kPassthroughYuvRgbConversion) &&
         base::FeatureList::IsEnabled(kUseMultiPlaneFormatForHardwareVideo);
}

#if BUILDFLAG(IS_WIN)
bool IsMediaFoundationD3D11VideoCaptureEnabled() {
  return base::FeatureList::IsEnabled(kMediaFoundationD3D11VideoCapture);
}
#endif

#if BUILDFLAG(ALLOW_OOP_VIDEO_DECODER)
bool IsOutOfProcessVideoDecodingEnabled() {
#if BUILDFLAG(IS_CASTOS)
  // The sandbox for OOP-VD was designed assuming that we're not on CastOS (see
  // go/oop-vd-sandbox).
  //
  // TODO(b/210759684): revisit the sandbox to see if this restriction is
  // necessary.
  return false;
#else
  return base::FeatureList::IsEnabled(kUseOutOfProcessVideoDecoding);
#endif
}
#endif  // BUILDFLAG(ALLOW_OOP_VIDEO_DECODER)

// Return bitmask of audio formats supported by EDID.
uint32_t GetPassthroughAudioFormats() {
#if BUILDFLAG(ENABLE_PASSTHROUGH_AUDIO_CODECS)
  // Return existing value if codec_bitmask has previously been retrieved,
  static const uint32_t codec_bitmask = []() {
    auto* command_line = base::CommandLine::ForCurrentProcess();
    uint32_t value = 0;
    if (command_line->HasSwitch(switches::kAudioCodecsFromEDID)) {
      base::StringToUint(
          command_line->GetSwitchValueASCII(switches::kAudioCodecsFromEDID),
          &value);
    }
    return value;
  }();
  return codec_bitmask;
#else
  return 0;
#endif  // BUILDFLAG(ENABLE_PASSTHROUGH_AUDIO_CODECS)
}

}  // namespace media
